#ifdef FSHIGHPRECISION
	precision highp float;
#else
	precision mediump float;
#endif

varying vec2 v_Texcoord0;
varying vec3 v_Normal;
varying vec3 v_Tangent;
varying vec3 v_Binormal;
varying vec3 v_ViewDir;

uniform vec4 u_AmbientColor;
uniform vec4 u_DiffuseColor;
uniform vec4 u_SpecularColor;

#ifdef DIFFUSETEXTURE
	uniform sampler2D u_DiffuseTexture;
#endif
#ifdef SPECULARTEXTURE
	uniform sampler2D u_SpecularTexture;
#endif
#ifdef NORMALTEXTURE
	uniform sampler2D u_NormalTexture;
	uniform float u_normalScale;
#endif
#ifdef PARALLAXTEXTURE
	uniform sampler2D u_ParallaxTexture;
	uniform float u_parallaxScale;
#endif
#ifdef OCCLUSIONTEXTURE
	uniform sampler2D u_OcclusionTexture;
	uniform float u_occlusionStrength;
#endif
#ifdef EMISSION
	#ifdef EMISSIONTEXTURE
		uniform sampler2D u_EmissionTexture;
	#endif
	uniform vec4 u_EmissionColor;
#endif

uniform float u_AlphaTestValue;
uniform float u_metallic;
uniform float u_smoothness;
uniform float u_smoothnessScale;

#include "PBRSpecularLighting.glsl"
#include "ShadowHelper.glsl"

varying float v_posViewZ;
#ifdef RECEIVESHADOW
	#if defined(SHADOWMAP_PSSM2)||defined(SHADOWMAP_PSSM3)
		uniform mat4 u_lightShadowVP[4];
	#endif
	#ifdef SHADOWMAP_PSSM1 
		varying vec4 v_lightMVPPos;
	#endif
#endif

uniform DirectionLight u_DirectionLight;

void main_castShadow()
{
	gl_FragColor=packDepth(v_posViewZ);
	#if defined(DIFFUSEMAP)&&defined(ALPHATEST)
		float alpha = texture2D(u_DiffuseTexture,v_Texcoord0).w;
		if( alpha < u_AlphaTestValue )
		{
			discard;
		}
	#endif
}

void main_normal()
{	
	vec3 viewDir = normalize(v_ViewDir);
	
	vec2 uv0 = ParallaxOffset(viewDir);
	
	vec4 sg;
	#ifdef DIFFUSETEXTURE
		vec4 diffuseTextureColor = texture2D(u_DiffuseTexture, uv0);
		vec4 diffuseColor = diffuseTextureColor * u_DiffuseColor;
		sg = SpecularGloss(diffuseTextureColor.a, uv0);
	#else
		vec4 diffuseColor = u_DiffuseColor;
		sg = SpecularGloss(1.0, uv0);
	#endif
	
	#ifdef ALPHATEST
		if(diffuseColor.a < u_AlphaTestValue)
			discard;
	#endif
  
	vec3 normal = UnpackScaleNormal(uv0);
	
	vec3 gi = (u_AmbientColor * Occlusion(uv0)).rgb;
	
	//float a = (sg.r+sg.g+sg.b) / 3.0;
  
	vec4 color = PBRSpecularDiectionLight(diffuseColor.rgb, sg.rgb, sg.a, normal,viewDir, u_DirectionLight, gi);
	
	color.a = diffuseColor.a;
	
	#ifdef EMISSION
		vec4 emissionColor = u_EmissionColor;
		#ifdef EMISSIONTEXTURE
			emissionColor *=  texture2D(u_EmissionTexture, uv0);
		#endif
		color.rgb += emissionColor.rgb;
	#endif
	
	#ifdef RECEIVESHADOW
		float shadowValue = 1.0;
		#ifdef SHADOWMAP_PSSM3
			shadowValue = getShadowPSSM3( u_shadowMap1,u_shadowMap2,u_shadowMap3,u_lightShadowVP,u_shadowPSSMDistance,u_shadowPCFoffset,v_PositionWorld,v_posViewZ,0.001);
		#endif
		#ifdef SHADOWMAP_PSSM2
			shadowValue = getShadowPSSM2( u_shadowMap1,u_shadowMap2,u_lightShadowVP,u_shadowPSSMDistance,u_shadowPCFoffset,v_PositionWorld,v_posViewZ,0.001);
		#endif 
		#ifdef SHADOWMAP_PSSM1
			shadowValue = getShadowPSSM1( u_shadowMap1,v_lightMVPPos,u_shadowPSSMDistance,u_shadowPCFoffset,v_posViewZ,0.001);
		#endif
		gl_FragColor = vec4(color.rgb * shadowValue, color.a);
	#else
		gl_FragColor = color;
	#endif
}

void main()
{
	#ifdef CASTSHADOW		
		main_castShadow();
	#else
		main_normal();
	#endif  
}

